﻿using System;
using System.Linq;
using System.Collections.Generic;
using System.Text;
using Silvermoon.Navigation;
using Silvermoon.UI;
using Silvermoon.Controls.Base;
using Silvermoon.Animations;
using System.Drawing;
using Silvermoon.Controls;
using Silvermoon;

namespace Passwords.Pages
{
    public static class PageTransitions
    {

        /// <summary>
        /// Defines transitions between pages.
        /// </summary>
        public static void Initialize()
        {
            NavigationService.SetTransition<Page, DetailsPage>(PageTransitions.ZoomIn);
            NavigationService.SetTransition<DetailsPage, Page>(PageTransitions.ZoomOut);
            NavigationService.SetTransition<Page, LoginPage>(PageTransitions.Implode);
            NavigationService.SetTransition<DetailsPage, EditDetailsPage>(PageTransitions.Flip);
            NavigationService.SetTransition<EditDetailsPage, DetailsPage>(PageTransitions.Flip);
            NavigationService.SetTransition<PasswordsPage, DetailsPage>(PageTransitions.PasswordDetailsFlipIn);
            NavigationService.SetTransition<DetailsPage, PasswordsPage>(PageTransitions.PasswordDetailsFlipOut);
            NavigationService.SetTransition<Page, ItemPickerPage>(PageTransitions.ZoomIn);
            NavigationService.SetTransition<ItemPickerPage, Page>(PageTransitions.Implode);
            NavigationService.SetTransition<Page, StringPickerPage>(PageTransitions.EditTextIn);
            NavigationService.SetTransition<StringPickerPage, Page>(PageTransitions.EditTextOut);

            NavigationService.SetTransition<Page, EditCategoryPage>(PageTransitions.ShiftLeft);
            NavigationService.SetTransition<EditCategoryPage, Page>(PageTransitions.ShiftRight);
            NavigationService.SetTransition<Page, NewCategoryPage>(PageTransitions.FromBottom);
            NavigationService.SetTransition<NewCategoryPage, Page>(PageTransitions.ToBottom);

            NavigationService.SetTransition<LabelPickerPage, EditLabelDetailPage>(PageTransitions.ShiftLeft);
            NavigationService.SetTransition<EditLabelDetailPage, LabelPickerPage>(PageTransitions.ShiftRight);
            NavigationService.SetTransition<LabelPickerPage, NewLabelDetailPage>(PageTransitions.FromBottom);
            NavigationService.SetTransition<NewLabelDetailPage, LabelPickerPage>(PageTransitions.ToBottom);

            NavigationService.SetTransition<Page, LabelIndexPicker>(PageTransitions.ZoomIn);
            NavigationService.SetTransition<LabelIndexPicker, Page>(PageTransitions.ZoomOut);
            NavigationService.SetTransition<Page, LabelTypePickerPage>(PageTransitions.ZoomIn);
            NavigationService.SetTransition<LabelTypePickerPage, Page>(PageTransitions.ZoomOut);
        }

        const int duration = 110;
        private static readonly ScaleTransform explodeTransform = new ScaleTransform(5f, 5f, 1f);
        private static readonly ScaleTransform minimizedTransform = new ScaleTransform(0.8f, 0.8f, 1f);
        private static readonly ScaleTransform zoomedTransform = new ScaleTransform(0.5f, 0.5f, 1f);

        public static readonly PageTransition EditTextIn = new PageTransition
        {
            Mode = PageTransitionMode.HideAndShow,
            Source = new VisualState("", new IntTransition(FormBase.OpacityProperty, 100, null, 0, LinearEase.Instance)),
            Target = new VisualState(VState.Shown,
                new FloatTransition(Page.VisibilityProperty, 50, 0f, 1f, LinearEase.Instance),
                new IntTransition(Page.OpacityProperty, 30, 0, 255, ExponentialEase.Out),
                new FloatTransition(StringPickerPage.RotationProperty, 250, 80F, 0F, LinearEase.Instance)),
        };

        public static readonly PageTransition EditTextOut = new PageTransition
        {
            Mode = PageTransitionMode.HideAndShow,
            Source = new VisualState(VState.Hidden,
                new IntTransition(Page.OpacityProperty, 50, null, 0, ExponentialEase.In) { Delay = 150 },
                new FloatTransition(StringPickerPage.RotationProperty, 200, null, 90F, CircleEase.In)),

            Target = new VisualState("", new IntTransition(FormBase.OpacityProperty, 250, 0, 255))
        };

        public static readonly PageTransition FadeIn = new PageTransition
        {
            Mode = PageTransitionMode.Show,
            Target = new VisualState("", new IntTransition(FormBase.OpacityProperty, 350, 0, 255, LinearEase.Instance))
        };

        public static readonly PageTransition FadeOut = new PageTransition
        {
            Mode = PageTransitionMode.Hide,
            Source = new VisualState("", new IntTransition(FormBase.OpacityProperty, 400, null, 0, LinearEase.Instance))
        };

        public static readonly PageTransition ShiftLeft = new PageTransition
        {
            Mode = PageTransitionMode.HideAndShow,
            Source = new VisualState("", new FloatTransition(FormBase.TranslateXFactorProperty, 300, null, -1f, PowerEase.Out)),
            Target = new VisualState("", new FloatTransition(FormBase.TranslateXFactorProperty, 300, 1f, 0f, PowerEase.Out)),
        };

        public static readonly PageTransition ShiftRight = new PageTransition
        {
            Mode = PageTransitionMode.HideAndShow,
            Source = new VisualState("", new FloatTransition(FormBase.TranslateXFactorProperty, 300, null, 1f, PowerEase.Out)),
            Target = new VisualState("", new FloatTransition(FormBase.TranslateXFactorProperty, 300, -1f, 0f, PowerEase.Out)),
        };

        public static readonly PageTransition Implode = new PageTransition
        {
            Mode = PageTransitionMode.Show,
            Target = new VisualState("",
                new IntTransition(Control.OpacityProperty, 350, 0, 255, PowerEase.In),
                new ScaleTransition(350, explodeTransform, ScaleTransform.One, PowerEase.QuadraticOut))
        };

        public static readonly PageTransition Explode = new PageTransition
        {
            Mode = PageTransitionMode.Hide,
            Source = new VisualState("",
                new IntTransition(Control.OpacityProperty, 350, null, 0, LinearEase.Instance),
                new ScaleTransition(350, null, explodeTransform, PowerEase.In))

        };

        public static readonly PageTransition ZoomIn = new PageTransition
        {
            Mode = PageTransitionMode.Show,
            Target = new VisualState("",
                new IntTransition(Control.OpacityProperty, 200, 0, 255, PowerEase.Out),
                new ScaleTransition(300, zoomedTransform, ScaleTransform.One, PowerEase.QuadraticOut))
        };

        public static readonly PageTransition ZoomOut = new PageTransition
        {
            Mode = PageTransitionMode.Hide,
            Source = new VisualState("",
                new IntTransition(Control.OpacityProperty, 300, null, 0, PowerEase.CubicIn),
                new ScaleTransition(300, null, zoomedTransform, PowerEase.In))
        };


        public static readonly PageTransition FromBottom = new PageTransition
        {
            Mode = PageTransitionMode.Show,
            Target = new VisualState("", new FloatTransition(FormBase.TranslateYFactorProperty, 300, 1f, 0f, PowerEase.Out))
        };

        public static readonly PageTransition ToBottom = new PageTransition
        {
            Mode = PageTransitionMode.Hide,
            Source = new VisualState("", new FloatTransition(FormBase.TranslateYFactorProperty, 300, null, 1f, PowerEase.In))
        };

        public static readonly PageTransition RotateLeftIn = new PageTransition
        {
            Mode = PageTransitionMode.HideThenShow,
            Source = new VisualState("", new FloatTransition(FormBase.RotateVerticalProperty, 350, 2f * -360F, 2f * -360F + 90F, CircleEase.Out)),
            Target = new VisualState("", new FloatTransition(FormBase.RotateVerticalProperty, 350, -360f * 2f + 90F, 2f * -360F, CircleEase.In))
        };

        public static readonly PageTransition RotateLeftOut = new PageTransition
        {
            Mode = PageTransitionMode.HideThenShow,
            Source = new VisualState("", new FloatTransition(FormBase.RotateVerticalProperty, 350, -360f * 2f, 2f * -360F - 90F, CircleEase.Out)),
            Target = new VisualState("", new FloatTransition(FormBase.RotateVerticalProperty, 350, -360f * 2f + 90F, 2f * -360F, CircleEase.In))
        };

        public static readonly PageTransition Flip = new PageTransition
        {
            Mode = PageTransitionMode.HideThenShow,
            Source = new VisualState("", new FloatTransition { Property = FormBase.RotateHorizonProperty, To = 90F, EasingFunction = CircleEase.In, Duration = duration }),

            Target = new VisualState(VState.Shown,
                new FloatTransition { Property = FormBase.VisibilityProperty, From = -0f, To = 1F, EasingFunction = LinearEase.Instance, Duration = duration },
                new IntTransition(FormBase.OpacityProperty, 1, null, 255),
                new FloatTransition { Property = FormBase.RotateHorizonProperty, From = -90F, To = 0F, EasingFunction = BackEase.Out, Duration = duration * 4 }),

        };

        public static readonly PageTransition InOut = new PageTransition
        {
            Mode = PageTransitionMode.HideThenShow,
            Source = new VisualState("",
                //                new IntTransition(Control.OpacityProperty, 150, null, 0, PowerEase.QuadraticIn),
                new ScaleTransition(100, null, minimizedTransform, PowerEase.QuadraticIn)
                ),

            Target = new VisualState("",
            new IntTransition(Control.OpacityProperty, 200, 0, 255, LinearEase.Instance),
            new ScaleTransition(250, explodeTransform, ScaleTransform.One, PowerEase.Out))
        };

        public static PageTransition OutIn = new PageTransition
        {
            Mode = PageTransitionMode.HideThenShow,
            Source = new VisualState("",
                new IntTransition(Control.OpacityProperty, 200, null, 0, PowerEase.QuadraticIn),
                new ScaleTransition(250, null, explodeTransform, PowerEase.QuadraticIn)),

            Target = new VisualState("",
                //            new IntTransition(Control.OpacityProperty, 100, 48, 255, LinearEase.Instance),
            new ScaleTransition(100, minimizedTransform, ScaleTransform.One, PowerEase.QuadraticOut))
        };

        public static PageTransition PasswordDetailsFlipIn = new PageTransition
        {
            Mode = PageTransitionMode.HideAndShow,
            Source = new VisualState("",
                new IntTransition(FormBase.OpacityProperty, 220, null, 0),
                new FloatTransition(FormBase.TranslateYFactorProperty, 220, 0f, -0.5f)
                ),
            Target = new VisualState(VState.Shown,
                new FloatTransition { Property = FormBase.VisibilityProperty, Duration = 250, EasingFunction = LinearEase.Instance, From = 0f, To = 1f },
                new FloatTransition { Property = DetailsPage.ViewTransformationProperty, Duration = 250, EasingFunction = PowerEase.Out, From = -0.7f, To = 0f, Delay = 120 },
                new IntTransition { Property = FormBase.OpacityProperty, Duration = 300, EasingFunction = PowerEase.Out, From = 0, To = 255, },
                new PointTransition { Property = DetailsPage.TitleTransformationProperty, Duration = 400, EasingFunction = PowerEase.Out, From = new Point(300, -110), To = Point.Empty, Delay = 320 }
                )
        };

        public static PageTransition PasswordDetailsFlipOut = new PageTransition
        {
            Mode = PageTransitionMode.HideAndShow,
            Source = new VisualState(VState.Hidden,
                    new IntTransition { Property = FormBase.OpacityProperty, Duration = 350, EasingFunction = PowerEase.In, To = 0, },
                    new FloatTransition { Property = DetailsPage.ViewTransformationProperty, Duration = 360, EasingFunction = PowerEase.In, To = -0.7f },
                    new PointTransition { Property = DetailsPage.TitleTransformationProperty, Duration = 360, EasingFunction = PowerEase.Out, To = new Point(-400, -110) }
            ),
            Target = new VisualState("",
                new IntTransition(FormBase.OpacityProperty, 220, 0, 255, ExponentialEase.Out),
                new FloatTransition(FormBase.TranslateYFactorProperty, 400, 1f, 0f, PowerEase.QuadraticOut)
                )
        };
    }

}

